using System;
using System.Collections.Generic;
using System.Text;
using Umdf.ComInterop;
using System.Net.Sockets;
using Umdf.SideShow.Scf;
using System.Net;
using System.IO;

namespace Umdf.SideShow.PocketPC
{
    [SideShowDeviceMetadata("PocketPC", "Xander en Mark", "1.0")]
    [SideShowSupportedEndpoint(SideShowConstants.ScfFormat)]
    public class PocketPCSideShowDriver : SideShowDriver, ICallbackChannel
    {
        private TcpListener _listener;
        private const int TCP_LISTEN_PORT = 14000;
        private PocketPCServerChannel _channel;

        protected override bool Initialize()
        {
            IPHostEntry entry = Dns.GetHostEntry(Dns.GetHostName());
            IPAddress addr = IPAddress.Parse("127.0.0.1"); // entry.AddressList[0];
            _listener = new TcpListener(IPAddress.Any, TCP_LISTEN_PORT);
            _listener.Start();
            _listener.BeginAcceptTcpClient(AcceptTcpClientCallback, null);
            return true;
        }

        protected override void Deinitialize()
        {
            base.Deinitialize();
            if (_channel != null)
            {
                _channel.Deinitialize();
            }
            _listener.Stop();
        }

        protected override void OnAddApplication(SideShowApplication app)
        {
            base.OnAddApplication(app);
            if (_channel != null)
            {
                _channel.AddApplication(app);
            }
        }

        protected override void OnAddContent(SideShowApplication application, SideShowEndpoint sideShowEndpoint, Umdf.SideShow.Contents.Content newContent)
        {
            base.OnAddContent(application, sideShowEndpoint, newContent);
            if (_channel != null)
            {
                _channel.AddContent(application.Id, sideShowEndpoint.Id, newContent);
            }
        }

        protected override void OnRemoveApplication(SideShowApplication app)
        {
            base.OnRemoveApplication(app);
            if (_channel != null)
            {
                _channel.RemoveApplication(app.Id);
            }
        }

        protected override void OnRemoveContent(SideShowApplication application, SideShowEndpoint sideShowEndpoint, Umdf.SideShow.Contents.Content newContent)
        {
            base.OnRemoveContent(application, sideShowEndpoint, newContent);
            if (_channel != null)
            {
                _channel.RemoveContent(application.Id, sideShowEndpoint.Id, newContent.Id);
            }
        }

        private void AcceptTcpClientCallback(IAsyncResult result)
        {
            if (result.IsCompleted)
            {
                try
                {
                    TcpClient client = _listener.EndAcceptTcpClient(result);
                    _channel = new PocketPCServerChannel(client, this);
                    _channel.Closed += new EventHandler(ConnectionClosed);
                    _channel.Initialize();
                    SendApplicationList();
                }
                catch
                {
                }
            }
        }

        protected override void OnError(Guid applicationId, Guid endpointId, uint contentId)
        {
            base.OnError(applicationId, endpointId, contentId);
        }

        private void ConnectionClosed(object sender, EventArgs e)
        {
            _listener.BeginAcceptTcpClient(AcceptTcpClientCallback, null);
        }

        private void SendApplicationList()
        {
            foreach (SideShowApplication app in this.Applications)
            {
                _channel.AddApplication(app);
            }
        }

        
    }
}
